// 参考: https://github.com/Icemic/Aliyun-DDNS-Docker
const RPCClient = require('@alicloud/pop-core').RPCClient;
const { onMsg, request } = require(`${process.root}/util`);
const CONFIG = require(`${process.root}/config`)
const reg = /ali-ddns\s+?(?<action>(update))/;
module.exports = {
  name: 'ali-ddns',
  main: ({ data }) => {
    if (!CONFIG.plugins["ali-ddns"]) return;
    onMsg(data, async msg => {
      const res = reg.exec(msg);
      if (!res) return;
      const action = res.groups?.action;
      if (!action) return { message: 'ali-ddns: 参数错误' }
      let message;
      try {
        switch (action) {
          case 'update':
            message = await onUpdate();
        }
      } catch (e) {
        message = e
      }
      return { message }
    }, { checkAdmin: true })
  }
}

async function getIP(url) {
  try {
    const res = await request({ method: 'get', url });
    return Promise.resolve(res.data);
  } catch {
    return Promise.reject('公网ip获取失败');
  }
}

async function onDescribeDomainRecords(client, DomainName, RRKeyWord, TypeKeyWord) {
  return client.request('DescribeDomainRecords', {
    DomainName,
    RRKeyWord,
    TypeKeyWord,
    PageSize: 100,
    TTL: 600,
  }, {
    timeout: 3000, // default 3000 ms
    formatAction: true, // default true, format the action to Action
    formatParams: true, // default true, format the parameter name to first letter upper case
    method: 'GET', // set the http method, default is GET
    headers: {}, // set the http request headers
  });
}

async function onAddDomainRecord(client, DomainName, RR, Type, Value) {
  return client.request('AddDomainRecord', {
    DomainName,
    RR,
    Type,
    Value,
    TTL: 600,
  }, {
    timeout: 3000, // default 3000 ms
    formatAction: true, // default true, format the action to Action
    formatParams: true, // default true, format the parameter name to first letter upper case
    method: 'GET', // set the http method, default is GET
    headers: {}, // set the http request headers
  });
}

async function onUpdateDomainRecord(client, RecordId, RR, Type, Value) {
  return client.request('UpdateDomainRecord', {
    RecordId,
    RR,
    Type,
    Value,
    TTL: 600,
  }, {
    timeout: 3000, // default 3000 ms
    formatAction: true, // default true, format the action to Action
    formatParams: true, // default true, format the parameter name to first letter upper case
    method: 'GET', // set the http method, default is GET
    headers: {}, // set the http request headers
  });
}

async function onUpdate() {
  let message = 'ali-ddns: ';
  const { AccessKeyId, AccessKeySecret, IpApi, Domain, SubDomain, TypeKeyWord } = CONFIG.plugins["ali-ddns"];
  const client = new RPCClient({
    accessKeyId: AccessKeyId,
    accessKeySecret: AccessKeySecret,
    endpoint: 'https://alidns.aliyuncs.com',
    apiVersion: '2015-01-09'
  });

  try {
    const ip = await getIP(IpApi);
    const list = await onDescribeDomainRecords(client, Domain, SubDomain, TypeKeyWord);

    let hasRecord = false;
    let recordId;
    if (list.DomainRecords && list.DomainRecords.Record && list.DomainRecords.Record.length) {
      for (const record of list.DomainRecords.Record) {
        if (record.DomainName === Domain && record.RR === SubDomain) {
          if (record.Value === ip) {
            message += '公网IP未变化'
            return Promise.reject(message);
          }
          hasRecord = true;
          recordId = record.RecordId;
        }
      }
    }
    let result;
    if (!hasRecord) {
      message += '当前无记录';
      result = await onAddDomainRecord(client, Domain, SubDomain, TypeKeyWord, ip);
    } else {
      message += '当前有记录';
      result = await onUpdateDomainRecord(client, recordId, SubDomain, TypeKeyWord, ip);
    }
    if (result.RequestId) {
      message += ', 设置成功';
    }
  } catch (e) {
    if (typeof e === 'string') message += e;
    else if (typeof e?.message === 'string') message += e.message;
    else message += '更新失败'
    return Promise.reject(message);
  }
  return Promise.resolve(message);
}

